// wait_group 实现有条件的等待
#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/WFHttpServer.h>
#include <iostream>
#include <signal.h>
using std::cout;
using std::cerr;
using std::string;
struct SeriesContext{
    string username;
    string password;
    protocol::HttpResponse *resp;
};
static WFFacilities::WaitGroup waitGroup(1);
void handler(int signum){
    cout << "done\n";
    waitGroup.done();
}
void serverCallback(WFHttpTask * serverTask){
    cout << "serverCallback is called!\n";
}
void redisCallback(WFRedisTask * redisTask){
    cout << "redisCallback is called!\n";
    protocol::RedisRequest *req = redisTask->get_req();
	protocol::RedisResponse *resp = redisTask->get_resp();
	int state = redisTask->get_state();
	int error = redisTask->get_error();
    // val用来保存redis执行的结果
	protocol::RedisValue val;
    switch (state){
	case WFT_STATE_SYS_ERROR:
		cerr <<"system error: " << strerror(error) << "\n";
		break;
	case WFT_STATE_DNS_ERROR:
		cerr <<"DNS error: "  << gai_strerror(error) << "\n";
		break;
	case WFT_STATE_SSL_ERROR:
		cerr <<"SSL error\n";
		break;
	case WFT_STATE_TASK_ERROR:
		cerr <<"Task error\n";
		break;
	case WFT_STATE_SUCCESS:
    	resp->get_result(val);// 将redis的执行结果保存起来
		if (val.is_error()){
		   cerr <<  "Error reply. Need a password?\n";
		   state = WFT_STATE_TASK_ERROR;
		}
		break;
	}
	if (state != WFT_STATE_SUCCESS){
		cerr <<  "Failed. Press Ctrl-C to exit.\n";
		return;
	}
    // 从context中取出一些信息
    SeriesContext * context = static_cast<SeriesContext *>(series_of(redisTask)->get_context());
	if(val.is_string() && val.string_value() == context->password){
        context->resp->append_output_body("login success!");
		
	}
    else{
        context->resp->append_output_body("login failed!");
    }
    cout << "redisCallback is done!\n";
}
void process(WFHttpTask * serverTask){
    //serverTask是服务端任务 是分离的
    cout << "process is called!\n";
    // 读取请求 写入响应
    protocol::HttpRequest *req = serverTask->get_req();
    protocol::HttpResponse *resp = serverTask->get_resp();
    // 提取请求的信息
    string method = req->get_method();
    string url = req->get_request_uri();
    string path = url.substr(0,url.find("?"));
    string query = url.substr(url.find("?")+1);
    string nameKV = query.substr(0,query.find("&"));
    string name = nameKV.substr(nameKV.find("=")+1);
    string passwordKV = query.substr(query.find("&")+1);
    string password = passwordKV.substr(passwordKV.find("=")+1);

    // 将password存入series的context中
    SeriesContext * context = new SeriesContext;
    context->password = password;
    context->username = name;
    context->resp = resp;
    series_of(serverTask)->set_context(context);

    //创建redis任务
    WFRedisTask * redisTask = WFTaskFactory::create_redis_task("redis://127.0.0.1:6379",10,redisCallback);
    redisTask->get_req()->set_request("HGET",{"60user",name});
    series_of(serverTask)->push_back(redisTask);

    serverTask->set_callback(serverCallback);
    cout << "process is done!\n";
}
int main(){
    signal(SIGINT,handler);
    // 构造了一个server对象
    WFHttpServer server(process);
    // 开启监听
    if(server.start(1234) == 0){
        cout << "server start success!\n";
        waitGroup.wait(); //阻塞住主线程
        server.stop(); // 停止监听
    }
    else{
        perror("server start");
        return -1;
    }
    return 0;
}
